import { asyncRoutes, constantRoutes } from '@/router'

/**
 * Use meta.role to determine if the current user has permission
 * @param roles
 * @param route
 */
function hasPermission(roles, route) {
  if (route.meta && route.meta.roles) {
    return roles.some(role => route.meta.roles.includes(role))
  } else {
    return true
  }
}

/**
 * Filter asynchronous routing tables by recursion
 * @param routes asyncRoutes
 * @param roles
 */
export function filterAsyncRoutes(routes, roles) {
  const res = []

  routes.forEach(route => {
    const tmp = { ...route }
    if (hasPermission(roles, tmp)) {
      if (tmp.children) {
        tmp.children = filterAsyncRoutes(tmp.children, roles)
      }
      res.push(tmp)
    }
  })

  return res
}

/**
 * 根据name找出路由并返回
 * @param asyncRouterMap
 * @param name
 */
function inRouterMap(asyncRouterMap, name) {
  let router = false
  if (undefined === name) {
    return router
  }
  for (let i = 0, len = asyncRouterMap.length; i < len; i++) {
    if (asyncRouterMap[i].name === name) {
      router = asyncRouterMap[i]
      break
    } else if (asyncRouterMap[i].children) {
      router = inRouterMap(asyncRouterMap[i].children, name)
      if (router) {
        break
      }
    }
  }
  return router
}

/**
 * 根据permissionList(的标记)改变asyncRouterMap中相应路由的roles，并给路由meta属性增加buttons属性（表示button的权限）
 * @param asyncRouterMap
 * @param permissionList
 * @param roles
 */
function filterPermissionList(asyncRouterMap, permissionList, roles) {
  for (let i = 0, len = permissionList.length; i < len; i++) {
    if (permissionList[i].checked !== null) {
      const router = inRouterMap(asyncRouterMap, permissionList[i].sysAclComponentName)
      if (router) {
        if (!router.meta) {
          router.meta = {}
        }
        if (!router.meta.roles) {
          router.meta.roles = []
        }
        // router.meta.roles = []
        if (permissionList[i].checked === true) {
          router.meta.roles = router.meta.roles.concat(roles)
        } else {
          router.meta.roles = router.meta.roles.concat(['no permission'])
        }
      }
    }
    if (permissionList[i].sysAclType === 2 || permissionList[i].sysAclType === '2' || permissionList[i].sysAclType === 3 || permissionList[i].sysAclType === '3') {
      routerAddButton(asyncRouterMap, permissionList[i], permissionList[i].sysAclRouter)
    }
    let acls = []
    if (permissionList[i].children instanceof Array) {
      acls = permissionList[i].children
    }
    if (acls.length > 0) {
      filterPermissionList(asyncRouterMap, acls, roles)
    }
  }
}

/**
 * 设置路由的按钮
 * @param asyncRouterMap
 * @param button
 * @param router
 */
function routerAddButton(asyncRouterMap, button, router) {
  const parentRouter = inRouterMap(asyncRouterMap, router)
  if (parentRouter) {
    if (!parentRouter.meta.buttons) {
      parentRouter.meta.buttons = {}
    }
    parentRouter.meta.buttons[button.sysAclAction] = button.checked
  }
}

/**
 * 设置路由的redirect属性
 * @param accessedRouters
 */
function settingRedirect(accessedRouters) {
  changeRedirect(accessedRouters)

  function changeRedirect(routers) {
    routers.map((item, index) => {
      if (item.children && item.children.length) {
        item.redirect = {
          name: item.children[0].name
        }
        changeRedirect(item.children)
      }
      if (item.name === 'Root') {
        if (routers[index + 1] && routers[index + 1].path) {
          item.redirect = routers[index + 1].path
        } else {
          item.redirect = '/404'
        }
      }
    })
  }
}

/**
 * 设置父路由的角色
 * @param routes
 * @param roles
 */
function setParent(routes, roles) {
  routes.map((item, index) => {
    if (item.children && item.children.length) {
      if (item.children.some(_ => _.meta && _.meta.roles && _.meta.roles.includes(roles[0]))) {
        item.meta = item.meta || {}
        item.meta.roles = item.meta.roles || []
        if (!item.meta.roles.includes(roles)) {
          item.meta.roles = item.meta.roles.concat(roles)
        }
      }
      setParent(item.children, roles)
    }
  })
}

const state = {
  routes: [],
  addRoutes: []
}

const mutations = {
  SET_ROUTES: (state, routes) => {
    state.addRoutes = routes
    state.routes = constantRoutes.concat(routes)
  }
}

const actions = {
  generateRoutes({ commit }, data) {
    return new Promise(resolve => {
      const { roles, acls } = data
      let accessedRoutes
      if (roles.includes('admin') && false) {
        accessedRoutes = asyncRoutes || []
      } else {
        console.log(asyncRoutes)
        filterPermissionList(asyncRoutes, acls, roles)
        setParent(asyncRoutes, roles)
        accessedRoutes = filterAsyncRoutes(asyncRoutes, roles)
      }
      commit('SET_ROUTES', accessedRoutes)
      resolve(accessedRoutes)
    })
  }
}

export default {
  namespaced: true,
  state,
  mutations,
  actions
}
